package com.libgdxbar.pvzlikegame.screens;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.utils.Disposable;

import java.util.HashMap;
import java.util.Map;

public class ScreenManager implements Disposable {
	private static ScreenManager instance;
	private final Map<Class<?>, GameScreen> screens = new HashMap<>();
	private GameScreen curScreen;
	private GameScreen launchScreen;
	private InputMultiplexer imp = new InputMultiplexer();

	/**
	 * 单例屏幕管理器
	 */
	public static synchronized ScreenManager getInstance() {
		//初始化语句
		if (instance == null){
			instance = new ScreenManager();
			Gdx.input.setInputProcessor(instance.imp);
		}
		return instance;
	}

	/**
	 * 渲染(已初始化的)当前屏幕
	 */
	public void render() {
		if (!curScreen.isInitialized()) return;
		float delta = Gdx.graphics.getDeltaTime();
		curScreen.render(delta);
	}

	/**
	 * 释放资源
	 */
	@Override
	public void dispose() {
		for (GameScreen screen : screens.values()) {
			if (screen.isInitialized())
				screen.dispose();
		}
	}

	public void resize(int width, int height) {
		curScreen.resize(width, height);
	}

	/**
	 * 添加并配置游戏屏幕
	 */
	public ScreenManager addScreen(GameScreen screen) {
		Class<?> key = screen.getClass();
		if (!screens.containsKey(key)) {
			screens.put(key, screen);
			screen.setScreenManager(this);
			screen.setImp(new InputMultiplexer());
		}
		if (curScreen == null) curScreen = screen;
		return this;
	}

	/**
	 * 通过键获取游戏屏幕
	 */
	public GameScreen getScreen(Class<?> key) {
		if (!screens.containsKey(key)) throw new RuntimeException("未找到此屏幕." + key.getSimpleName());
		return screens.get(key);
	}

	/**
	 * 获取当前屏幕
	 */
	public GameScreen getCurScreen() {
		return curScreen;
	}

	public void setCurScreen(Class<?> key) {
		setCurScreen(getScreen(key));
	}

	public void setCurScreen(GameScreen screen) {
		screen.initialize();
		if (this.curScreen != null) this.curScreen.hide();
		this.curScreen = screen;
		this.curScreen.show();
		this.curScreen.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
	}

	public GameScreen getLaunchScreen() {
		return launchScreen;
	}

	public void setLaunchScreen(Class<? extends GameScreen> key) {
		setLaunchScreen(getScreen(key));
	}

	public void setLaunchScreen(GameScreen screen) {
		launchScreen = screen;
		if (!screen.isInitialized())
			setCurScreen(launchScreen);
	}

	public void enableInput(InputMultiplexer screenImp) {
		imp.addProcessor(screenImp);
	}

	public void disableInput(InputMultiplexer screenImp) {
		imp.removeProcessor(screenImp);
	}

}
